package com.fangyi.yunmusic.websocket;

import com.alibaba.fastjson.JSON;
import com.fangyi.yunmusic.pojo.vo.UserVO;
import com.fangyi.yunmusic.pojo.ws.CommentNotification;
import com.fangyi.yunmusic.service.notification.ArtistReviewNotificationService;
import com.fangyi.yunmusic.service.notification.CommentNotificationService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import javax.websocket.Session;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class CommentNotificationHandler extends TextWebSocketHandler{

    private Logger logger = LoggerFactory.getLogger(CommentNotificationHandler.class);

    private static Map<String, WebSocketSession> livingSessionMap = new ConcurrentHashMap<>();

    @Autowired
    private CommentNotificationService commentNotificationService;

    @Autowired
    private ArtistReviewNotificationService artistReviewNotificationService;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        String userId = (String) session.getAttributes().get("userId");
        livingSessionMap.put(userId, session);
        logger.info(userId + "进入连接");
        // 将用户未读的消息数传给用户
        sendNotReadNum(userId);
        // 将歌手申请的结果发给用户
        sendArtistReviewResult(userId);
    }

    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
        super.handleMessage(session, message);
    }

    /**
     *  接收客户端信息，告知哪条评论已读了。
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String userId = (String) session.getAttributes().get("userId");
        logger.info(userId + "发送信息" + message);
        CommentNotification cn = JSON.parseObject(new String(message.asBytes()), CommentNotification.class);
        commentNotificationService.remove(cn.getUserId(), cn.getCommentId());
        // 不通知了，客户端自行减1
//        // 更新用户未读消息
//        sendNotReadNum(session, userId);
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        String userId = (String) session.getAttributes().get("userId");
        if(session.isOpen()){
            session.close();
        }
        logger.error("连接出现错误:" + exception.toString());
        livingSessionMap.remove(userId);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        String userId = (String) session.getAttributes().get("userId");
        livingSessionMap.remove(userId);
        logger.info(userId + "断开连接");
    }

    public void sendMessage(WebSocketSession session, String message) {
        try {
            session.sendMessage(new TextMessage(message));
        } catch (IOException e) {
            logger.error("发送失败", e);
        }
    }

    /**
     * 发送用户未读消息
     * @param userId
     */
    public void sendNotReadNum(String userId) {
        WebSocketSession session = livingSessionMap.get(userId);
        if (session == null) {
            return ;    // 如果为null，则用户未连接，什么都不做，等用户连接后，自然能从onOpen中获取到消息。
        }
        Long notReadNum = commentNotificationService.getSize(userId);
        CommentNotification commentNotification = new CommentNotification();
        commentNotification.setNotReadCommentNum(notReadNum);
        sendMessage(session, JSON.toJSONString(commentNotification));
    }

    /**
     * 发送歌手申请结果
     * @param userId
     */
    public void sendArtistReviewResult(String userId) {
        WebSocketSession session = livingSessionMap.get(userId);
        if (session == null) {
            return ;    // 如果为null，则用户未连接，什么都不做，等用户连接后，自然能从onOpen中获取到消息。
        }
        String result = artistReviewNotificationService.getNotificaction(userId);
        if (result != null) {
            sendMessage(session, result);
            artistReviewNotificationService.remove(userId);
        }

    }

    /**
     * 给多个用户发送未读信息
     * @param userIds
     */
    public void sendNotReadNumToMany(List<String> userIds) {
        userIds.forEach(this::sendNotReadNum);
    }

}
